/**
 * 多源API管理器测试验证程序
 * 用于验证多源数据聚合系统是否正常工作
 */
public class MultiAPIManagerTest {
    
    private MultiAPIManager multiAPIManager;
    private UserPreferences userPreferences;
    private Location testLocation;
    
    public static void main(String[] args) {
        MultiAPIManagerTest test = new MultiAPIManagerTest();
        test.runAllTests();
    }
    
    public MultiAPIManagerTest() {
        setupTestEnvironment();
    }
    
    /**
     * 设置测试环境
     */
    private void setupTestEnvironment() {
        System.out.println("=== 初始化测试环境 ===");
        
        // 创建用户偏好设置
        userPreferences = new UserPreferences();
        userPreferences.setPreferredUnits("metric");
        
        // 创建测试位置
        testLocation = new Location("Beijing");
        
        // 创建多源API管理器
        multiAPIManager = new MultiAPIManager(userPreferences);
        
        // 注册API服务
        registerAPIServices();
        
        System.out.println("测试环境初始化完成\n");
    }
    
    /**
     * 注册API服务
     */
    private void registerAPIServices() {
        System.out.println("正在注册API服务...");
        
        // 注册OpenWeatherMap服务
        WeatherAPIManager openWeatherService = new WeatherAPIManager(userPreferences);
        multiAPIManager.registerAPIService(openWeatherService);
        System.out.println("已注册: " + openWeatherService.getDisplayName());
        
        // 注册WeatherAPI.com服务
        WeatherAPIComService weatherAPIComService = new WeatherAPIComService(userPreferences);
        multiAPIManager.registerAPIService(weatherAPIComService);
        System.out.println("已注册: " + weatherAPIComService.getDisplayName());
        
        // 显示注册的服务
        System.out.println("总共注册了 " + multiAPIManager.getRegisteredServices().size() + " 个服务");
        for (WeatherAPIService service : multiAPIManager.getRegisteredServices()) {
            System.out.println("- " + service.getDisplayName() + " (" + service.getSourceId() + 
                             ") 优先级: " + service.getPriority() + 
                             " 状态: " + (service.isServiceAvailable() ? "可用" : "不可用"));
        }
        System.out.println();
    }
    
    /**
     * 运行所有测试
     */
    public void runAllTests() {
        System.out.println("=====================================");
        System.out.println("    多源API管理器功能验证测试");
        System.out.println("=====================================\n");
        
        try {
            // 1. 测试服务可用性
            testServiceAvailability();
            
            // 2. 测试故障切换策略
            testFailoverStrategy();
            
            // 3. 测试并行聚合策略
            testParallelAggregationStrategy();
            
            // 4. 测试最佳性能策略
            testBestPerformanceStrategy();
            
            // 5. 测试用户选择策略
            testUserSelectedStrategy();
            
            // 6. 测试缓存功能
            testCachingMechanism();
            
            // 7. 测试可靠性统计
            testReliabilityStatistics();
            
            // 8. 测试预报功能
            testForecastFunctionality();
            
            System.out.println("\n=====================================");
            System.out.println("    所有测试完成!");
            System.out.println("=====================================");
            
        } catch (Exception e) {
            System.err.println("测试过程中发生错误: " + e.getMessage());
            e.printStackTrace();
        } finally {
            // 清理资源
            multiAPIManager.shutdown();
        }
    }
    
    /**
     * 测试服务可用性
     */
    private void testServiceAvailability() {
        System.out.println("=== 测试1: 服务可用性检查 ===");
        
        for (WeatherAPIService service : multiAPIManager.getRegisteredServices()) {
            System.out.println("检查服务: " + service.getDisplayName());
            
            boolean available = service.isServiceAvailable();
            long latency = service.testConnection();
            APISourceInfo.APIStatus status = service.getAPIStatus();
            
            System.out.println("- 可用性: " + (available ? "可用" : "不可用"));
            System.out.println("- 延迟: " + (latency > 0 ? latency + "ms" : "连接失败"));
            System.out.println("- 状态: " + status);
            System.out.println("- API限制: " + service.getAPILimits());
            System.out.println();
        }
    }
    
    /**
     * 测试故障切换策略
     */
    private void testFailoverStrategy() {
        System.out.println("=== 测试2: 故障切换策略 ===");
        
        multiAPIManager.setAggregationStrategy(MultiAPIManager.AggregationStrategy.PRIMARY_FAILOVER);
        
        try {
            long startTime = System.currentTimeMillis();
            WeatherData currentWeather = multiAPIManager.getCurrentWeather(testLocation);
            long responseTime = System.currentTimeMillis() - startTime;
            
            if (currentWeather != null) {
                System.out.println("✓ 故障切换策略测试成功");
                System.out.println("- 响应时间: " + responseTime + "ms");
                System.out.println("- 温度: " + currentWeather.getTemperature() + "°C");
                System.out.println("- 湿度: " + currentWeather.getHumidity() + "%");
                System.out.println("- 描述: " + currentWeather.getDescription());
            } else {
                System.out.println("✗ 故障切换策略测试失败: 返回数据为null");
            }
            
        } catch (Exception e) {
            System.out.println("✗ 故障切换策略测试失败: " + e.getMessage());
        }
        
        System.out.println();
    }
    
    /**
     * 测试并行聚合策略
     */
    private void testParallelAggregationStrategy() {
        System.out.println("=== 测试3: 并行聚合策略 ===");
        
        multiAPIManager.setAggregationStrategy(MultiAPIManager.AggregationStrategy.PARALLEL_AGGREGATE);
        
        try {
            long startTime = System.currentTimeMillis();
            WeatherData aggregatedWeather = multiAPIManager.getCurrentWeather(testLocation);
            long responseTime = System.currentTimeMillis() - startTime;
            
            if (aggregatedWeather != null) {
                System.out.println("✓ 并行聚合策略测试成功");
                System.out.println("- 响应时间: " + responseTime + "ms");
                System.out.println("- 温度: " + aggregatedWeather.getTemperature() + "°C");
                System.out.println("- 湿度: " + aggregatedWeather.getHumidity() + "%");
                System.out.println("- 描述: " + aggregatedWeather.getDescription());
                
                // 检查是否是聚合数据
                if (aggregatedWeather.getDescription().contains("Aggregated")) {
                    System.out.println("- 数据类型: 多源聚合数据");
                } else {
                    System.out.println("- 数据类型: 单源数据");
                }
            } else {
                System.out.println("✗ 并行聚合策略测试失败: 返回数据为null");
            }
            
        } catch (Exception e) {
            System.out.println("✗ 并行聚合策略测试失败: " + e.getMessage());
        }
        
        System.out.println();
    }
    
    /**
     * 测试最佳性能策略
     */
    private void testBestPerformanceStrategy() {
        System.out.println("=== 测试4: 最佳性能策略 ===");
        
        multiAPIManager.setAggregationStrategy(MultiAPIManager.AggregationStrategy.BEST_PERFORMANCE);
        
        try {
            long startTime = System.currentTimeMillis();
            WeatherData performanceWeather = multiAPIManager.getCurrentWeather(testLocation);
            long responseTime = System.currentTimeMillis() - startTime;
            
            if (performanceWeather != null) {
                System.out.println("✓ 最佳性能策略测试成功");
                System.out.println("- 响应时间: " + responseTime + "ms");
                System.out.println("- 温度: " + performanceWeather.getTemperature() + "°C");
                System.out.println("- 描述: " + performanceWeather.getDescription());
            } else {
                System.out.println("✗ 最佳性能策略测试失败: 返回数据为null");
            }
            
        } catch (Exception e) {
            System.out.println("✗ 最佳性能策略测试失败: " + e.getMessage());
        }
        
        System.out.println();
    }
    
    /**
     * 测试用户选择策略
     */
    private void testUserSelectedStrategy() {
        System.out.println("=== 测试5: 用户选择策略 ===");
        
        multiAPIManager.setAggregationStrategy(MultiAPIManager.AggregationStrategy.USER_SELECTED);
        
        // 测试选择不同的API源
        String[] testSources = {"openweather", "weatherapi"};
        
        for (String sourceId : testSources) {
            System.out.println("测试用户选择源: " + sourceId);
            multiAPIManager.setPreferredSource(sourceId);
            
            try {
                long startTime = System.currentTimeMillis();
                WeatherData userSelectedWeather = multiAPIManager.getCurrentWeather(testLocation);
                long responseTime = System.currentTimeMillis() - startTime;
                
                if (userSelectedWeather != null) {
                    System.out.println("✓ 用户选择 " + sourceId + " 测试成功");
                    System.out.println("- 响应时间: " + responseTime + "ms");
                    System.out.println("- 温度: " + userSelectedWeather.getTemperature() + "°C");
                } else {
                    System.out.println("✗ 用户选择 " + sourceId + " 测试失败: 返回数据为null");
                }
                
            } catch (Exception e) {
                System.out.println("✗ 用户选择 " + sourceId + " 测试失败: " + e.getMessage());
            }
            
            System.out.println();
        }
    }
    
    /**
     * 测试缓存功能
     */
    private void testCachingMechanism() {
        System.out.println("=== 测试6: 缓存机制 ===");
        
        WeatherDataCache cache = multiAPIManager.getCache();
        
        // 第一次请求（应该从API获取）
        System.out.println("第一次请求（从API获取）:");
        long firstRequestTime = System.currentTimeMillis();
        WeatherData firstRequest = multiAPIManager.getCurrentWeather(testLocation);
        long firstResponseTime = System.currentTimeMillis() - firstRequestTime;
        
        if (firstRequest != null) {
            System.out.println("✓ 第一次请求成功");
            System.out.println("- 响应时间: " + firstResponseTime + "ms");
        }
        
        // 立即第二次请求（应该从缓存获取）
        System.out.println("第二次请求（从缓存获取）:");
        long secondRequestTime = System.currentTimeMillis();
        WeatherData secondRequest = multiAPIManager.getCurrentWeather(testLocation);
        long secondResponseTime = System.currentTimeMillis() - secondRequestTime;
        
        if (secondRequest != null) {
            System.out.println("✓ 第二次请求成功");
            System.out.println("- 响应时间: " + secondResponseTime + "ms");
            
            // 检查缓存效果
            if (secondResponseTime < firstResponseTime / 2) {
                System.out.println("✓ 缓存机制工作正常（响应时间显著减少）");
            } else {
                System.out.println("? 缓存效果不明显，可能从API重新获取");
            }
        }
        
        // 显示缓存统计
        System.out.println("缓存统计: " + cache.getCacheStats());
        System.out.println();
    }
    
    /**
     * 测试可靠性统计
     */
    private void testReliabilityStatistics() {
        System.out.println("=== 测试7: 可靠性统计 ===");
        
        WeatherDataCache cache = multiAPIManager.getCache();
        
        System.out.println("各API源可靠性统计:");
        for (WeatherAPIService service : multiAPIManager.getRegisteredServices()) {
            String sourceId = service.getSourceId();
            double reliabilityScore = cache.getSourceReliabilityScore(sourceId);
            WeatherDataCache.SourceReliabilityStats stats = cache.getSourceStats(sourceId);
            
            System.out.println("源: " + service.getDisplayName() + " (" + sourceId + ")");
            System.out.println("- 可靠性分数: " + String.format("%.2f", reliabilityScore));
            
            if (stats != null) {
                System.out.println("- 成功次数: " + stats.getSuccessCount());
                System.out.println("- 失败次数: " + stats.getFailureCount());
                System.out.println("- 平均延迟: " + String.format("%.2f", stats.getAverageLatency()) + "ms");
                System.out.println("- 最后成功: " + (stats.getLastSuccess() != null ? stats.getLastSuccess() : "无"));
                System.out.println("- 最后失败: " + (stats.getLastFailure() != null ? stats.getLastFailure() : "无"));
            } else {
                System.out.println("- 暂无统计数据");
            }
            System.out.println();
        }
    }
    
    /**
     * 测试预报功能
     */
    private void testForecastFunctionality() {
        System.out.println("=== 测试8: 预报功能 ===");
        
        int[] testDays = {3, 5};
        
        for (int days : testDays) {
            System.out.println("测试 " + days + " 天预报:");
            
            try {
                long startTime = System.currentTimeMillis();
                WeatherData[] forecast = multiAPIManager.getForecast(testLocation, days);
                long responseTime = System.currentTimeMillis() - startTime;
                
                if (forecast != null && forecast.length > 0) {
                    System.out.println("✓ " + days + " 天预报获取成功");
                    System.out.println("- 响应时间: " + responseTime + "ms");
                    System.out.println("- 实际预报天数: " + forecast.length);
                    
                    // 显示前3天的预报
                    for (int i = 0; i < Math.min(3, forecast.length); i++) {
                        WeatherData day = forecast[i];
                        System.out.println("  第" + (i + 1) + "天: " + day.getTemperature() + "°C, " + 
                                         day.getDescription() + " (日期: " + day.getForecastDate() + ")");
                    }
                } else {
                    System.out.println("✗ " + days + " 天预报获取失败: 返回数据为null或空");
                }
                
            } catch (Exception e) {
                System.out.println("✗ " + days + " 天预报获取失败: " + e.getMessage());
            }
            
            System.out.println();
        }
    }
    
    /**
     * 显示测试总结
     */
    private void displayTestSummary() {
        System.out.println("=== 测试总结 ===");
        System.out.println("多源API管理器功能验证完成");
        System.out.println("当前配置:");
        System.out.println("- 聚合策略: " + multiAPIManager.getAggregationStrategy());
        System.out.println("- 首选源: " + multiAPIManager.getPreferredSource());
        System.out.println("- 注册服务数: " + multiAPIManager.getRegisteredServices().size());
        
        WeatherDataCache cache = multiAPIManager.getCache();
        System.out.println("- " + cache.getCacheStats());
    }
} 